<?php


/**
 * Description of AdminPresenter
 *
 * @author David Dusek
 */
use Nette\Application\UI\Form,
    CMS\User\Models\User;

class UserPresenter extends AdminPresenter
{
    public function renderDefault() {
        if (!$this->isAllowed("list")) {
            if ($this->isAllowed("detail")) {
                $this->redirect(":User:User:detail");
            } else {
                $this->flashMessage($this->dictionary->translate("user_noRightsErr"), "error");
                $this->redirect(":User:Login:");
            }
        }
        $this->template->title = $this->getTitle("title", "list");
    }
    
    public function renderAdd() {
        $this->isAllowed("add", TRUE);
        $this->template->title = $this->getTitle("title", "addUser");
    }
    
    public function renderEdit($id) {
        $this->isAllowed("edit", TRUE);
        $this->template->title = $this->getTitle("title", "editUser");
    }  
    
    public function renderDetail() {
        $this->isAllowed("detail", TRUE);                        
        $title = $this->getTitle("title", "detailUser");
        $this->template->title = $this->getTitle("title", "detailUser");
    }
    
//    public function renderChangePassword() {
//        $this->isAllowed("edit", TRUE);
//        $this->template->title = $this->getTitle("title", "changePassword");
//    }
    
    protected function createComponentGrid() {
        $grid = new Gridito\Grid($this, 'grid');
        $presenter = $this; 
       
        $qb = $this->em->getRepository('\CMS\User\Models\User')->createQueryBuilder('u')->where('u.deleted = 0');
        $em = $this->em;
        $grid->setModel(new CMS\DoctrineQueryBuilderModel($qb));
        $grid->addColumn('id', 'Id')->setSortable(true);
        $grid->addColumn('username', $this->translate('username'))->setSortable(true);
        $grid->addColumn('name', $this->translate('name'))->setSortable(true);
        $grid->addColumn('surname', $this->translate('surname'))->setSortable(true);
        $grid->addColumn('group.name', $this->translate('group'), array(
                'renderer' => function ($user) use ($presenter) {
                    echo \Nette\Utils\Html::el("a")->addAttributes(
                            array(
                                "href" => $presenter->link(':User:Group:rights', array("id" => $user->group->id))
                                ))->add($user->group->name);
                    } 
            ))->setSortable(true);
        $grid->addColumn('language', $this->translate('language'));
        
        $errMsg = $this->translate("deleteSucceeded");
        $presenter = $this;        
             
        if ($this->isAllowed("edit")) {
            $grid->addButton('editButton', $this->translate('edit'), array(
                            'icon' => 'ui-icon-pencil',
                            'handler' => function ($user) use ($presenter) {
                                $presenter->redirect(':User:User:edit', array("id" => $user->id));
                            },
                    ))
                    ->setShowText(false);
//            $grid->addButton('changePassword', $this->translate('changePassword'), array(
//                            'icon' => 'ui-icon-locked',
//                            'handler' => function ($user) use ($presenter) {
//                                $presenter->redirect(':User:User:changePassword', array("id" => $user->id));
//                            },
//                    ))
//                    ->setShowText(false);                        
        }
        
        if ($this->isAllowed("delete")) {
            $grid->addButton('deleteButton', $this->translate('delete'), array(
                            'icon' => 'ui-icon-trash',
                            'handler' => function ($user) use ($grid, $errMsg, $em) {
                                $user->setDeleted(TRUE);
                                $em->flush();
                                $grid->flashMessage(vsprintf($errMsg, array($user->name, $user->surname)));
                            },
                    ))
                    ->setConfirmationQuestion($this->translate('deleteConfirnQuestion'))
                    ->setShowText(false)
                    ->setAjax(true);
        }
    }
    
    /**
     * Vytvoreni formulare pro pridani a editaci informaci o uzivateli.
     * @return \Nette\Application\UI\Form 
     */
    protected function createComponentUserForm() {
        $form = new Form();
        $groups = $this->em->getRepository('\CMS\User\Models\Group')->findAll();       
        
        $groupsOptions = array();
        if (is_array($groups)) {
            foreach ($groups as $group) {
                $groupsOptions[$group->getId()] = $group->getName();
            }
        }
        
        $form->addText("name", $this->translate("name"))
                ->setRequired($this->translate('requiredErr'))
                ->addRule(Form::MAX_LENGTH, $this->translate("maxLenErr"), 45);
        $form->addText("surname", $this->translate('surname'))
                ->setRequired($this->translate('requiredErr'))
                ->addRule(Form::MAX_LENGTH, $this->translate("maxLenErr"), 45);
        
        if ($this->getAction() == "add") {
            $form->addText("username", $this->translate('username'))
                ->setRequired($this->translate('requiredErr'))
                ->addRule(Form::MAX_LENGTH, $this->translate("maxLenErr"), 45)
                ->addRule(Form::MIN_LENGTH, $this->translate("minLenErr"), 4);
            $form->addPassword("password", $this->translate("password"))
                ->setRequired($this->translate('requiredErr'))
                ->addRule(Form::MIN_LENGTH, $this->translate("minLenErr"), 6);
            $form->addPassword("passwordRep", $this->translate("passwordRep"))
                ->setRequired($this->translate('requiredErr'));
        } else {
            $form->addHidden("id");
        }
        
       
        $form->addText("degreeBefore", $this->translate("degreeBefore"));
        $form->addText("degreeAfter", $this->translate("degreeAfter"));       
        $form->addSelect("language", $this->translate('language'), $this->dictionary->availableLangs);
        $form->addSelect("group", $this->translate("group"), $groupsOptions);
        
        if ($this->getAction() == "add") {
            $form->addSubmit('add', $this->translate("add"));
        } else {
            $form->addSubmit('edit', $this->translate("edit"));
            $form->addSubmit('resetPass', $this->translate("resetPass"));
        }
        $form->onSuccess[] = callback($this, 'userFormSubmitted');
        
        // pokud byl formular odeslan ale obsahoval chybu tak ho inicializujeme                
        if ($this->getAction() == "edit") {
            $id = intval($this->getParameter("id"));
            
            if ($id > 0) {
                $userRep = $this->em->getRepository("\CMS\User\Models\User");
                $user = $userRep->find($id);
                // pokud dany uzivatel neexistuje
                if ($user === null) {
                    $this->flashMessage($this->translate("editWrongId"));
                    $this->redirect(":User:User:default");
                }

                $this->template->editedUser = $user;

                $user = $this->template->editedUser;
                $form->setDefaults(array(
                    "id" => $user->id,
                    "name" => $user->name,
                    "surname" => $user->surname,
                    "degreeBefore" => $user->degreeBefore,
                    "degreeAfter" => $user->degreeAfter,
                    "language" => $user->language,
                    "group" => $user->group->getId(),
                ));
            }
        }
        
        return $form;
    }
    
    /**
     * Formular s detailem prihlaseneho uzivatele a moznosti zmenit informace o sobe.
     * @return \Nette\Application\UI\Form 
     */
    protected function createComponentUserDetailForm() {
        $form = new Form();
        $form->addHidden("id");
        $form->addText("name", $this->translate("name"))
                ->setRequired($this->translate('requiredErr'))
                ->addRule(Form::MAX_LENGTH, $this->translate("maxLenErr"), 45);
        $form->addText("surname", $this->translate('surname'))
                ->setRequired($this->translate('requiredErr'))
                ->addRule(Form::MAX_LENGTH, $this->translate("maxLenErr"), 45);               
        $form->addText("degreeBefore", $this->translate("degreeBefore"));
        $form->addText("degreeAfter", $this->translate("degreeAfter"));  
        $form->addPassword('currPass', $this->translate("currentPassword"));
        $form->addPassword('password', $this->translate("newPassword"));
        $form->addPassword('passwordRep', $this->translate("passwordRep"));
        $form->addSelect("language", $this->translate('language'), $this->dictionary->availableLangs);
                
        $user = $this->em->getRepository("\CMS\User\Models\User")->find($this->getUser()->getId());
        $form->setDefaults(array(
            "id" => $user->id,
            "name" => $user->name,
            "surname" => $user->surname,
            "degreeBefore" => $user->degreeBefore,
            "degreeAfter" => $user->degreeAfter,
            "language" => $user->language,
        ));
        
        $form->addSubmit('edit', $this->translate("edit"));
        $form->onSuccess[] = callback($this, 'userDetailFormSubmitted');
        
        return $form;
    }
    
    /**
     * Zpracovani formulare z detailu uzivatele.
     * @param Form $form 
     */
    public function userDetailFormSubmitted(Form $form) {
        $values = $form->getValues();
        $user = $this->em->getRepository("\CMS\User\Models\User")->find($this->getUser()->getId());
        
        $user->setName($values["name"]);
        $user->setSurname($values["surname"]);
        $user->setDegreeAfter($values["degreeAfter"]);
        $user->setDegreeBefore($values["degreeBefore"]);
        $user->setLanguage($values["language"]);
        $this->user->getIdentity()->__set("lang", $values["language"]);
       
        if (isset($values["currPass"]) && !empty($values["currPass"])) {        
            $currPassword = sha1(substr($user->username, -3) . $values["currPass"]);        
            if ($user->password != $currPassword) {
                $form->addError($this->translate("currentPasswordWrong"));
            }

            if ($values["password"] != $values["passwordRep"]) {
                $form->addError($this->translate("passwordsNoMatch"));
            }

            if (!$form->hasErrors()) {
                $user->setPassword(sha1(substr($user->username, -3) . $values["password"]));                
            }
        }
        
        if (!$form->hasErrors()) {
            $this->em->flush();
            $this->flashMessage($this->translate("editSucceeded"));
            $this->redirect("this");
        }
    }
        
    /**
     * Zpracovani dat z formulare pro pridani a editaci uzivatele.
     * @param Form $form 
     */
    public function userFormSubmitted(Form $form) {
        $values = $form->getValues();        
        
        $error = FALSE;                
        $userRep = $this->em->getRepository("\CMS\User\Models\User");
        
        if ($this->getAction() == "add") {
            $user = new User();
            
            $sameUsername = $userRep->findBy(array("username" => $values["username"]));
            if ($this->getAction() == "add") {     
                if (count($sameUsername) != 0) {
                    $error = TRUE;
                    $form->addError(vsprintf($this->translate("usernameUsed"), array($values["username"])));
                }
            }
        } else {
            $user = $userRep->find($values["id"]);
            
            if ($user === null) {
                $this->flashMessage($this->translate("editWrongId"));
                $this->redirect(":User:User:default");
            }

            if ($form['resetPass']->submittedBy) {
                $characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
                $newPass = "";
                for ($i = 0; $i < 6; $i++) {
                    $newPass .= $characters[rand(0, strlen($characters) - 1)];
                }
                $user->setPassword(sha1(substr($user->username, -3) . $newPass));
                $this->em->flush();
                $this->flashMessage(vsprintf($this->translate("passResetSucceeded"), $newPass));
                $this->redirect(":User:User:edit", array("id" => $user->id));
            }
        }
        
        if ($this->getAction() == "add") {
            if ($values["password"] != $values["passwordRep"]) {
                $error = TRUE;
                $form->addError($this->translate("passwordsNoMatch"));
            }
            $user->setUsername($values["username"]);
            $pass = sha1(substr($values["username"], -3) . $values["password"]);
            $user->setPassword($pass);        
        }
                
        $user->setName($values["name"]);
        $user->setSurname($values["surname"]);
        $user->setDegreeAfter($values["degreeAfter"]);
        $user->setDegreeBefore($values["degreeBefore"]);
        $user->setLanguage($values["language"]);
        $this->user->getIdentity()->__set("lang", $values["language"]);
        
        $group = $this->em->getRepository('\CMS\User\Models\Group')->find($values["group"]);
        if ($group !== null) {
            $user->setGroup($group);
        }
        
        if (!$form->hasErrors()) {
            $this->em->persist($user);
            $this->em->flush();
            
            if ($this->getAction() == "add") {
                $this->flashMessage($this->translate("addSucceeded"));
            } else {
                $this->flashMessage($this->translate("editSucceeded"));
            }
            
            $this->redirect(":User:User:edit", array("id" => $user->id));
        }
    }  
    
    // TODO: odstranit
    protected function createComponentChangePasswordForm() {
        $form = new Form();

        $form->addHidden("id");
        $form->addPassword('currPass', $this->translate("currentPassword"))
            ->setRequired($this->translate("requiredErr"));
        $form->addPassword('password', $this->translate("newPassword"))
            ->setRequired($this->translate("requiredErr"))
            ->addRule(Form::MIN_LENGTH, $this->translate("minLenErr"), 4);
        $form->addPassword('passwordRep', $this->translate("passwordRep"))
            ->setRequired($this->translate("requiredErr"))
            ->addRule(Form::MIN_LENGTH, $this->translate("minLenErr"), 4);
        $form->addSubmit('change', $this->translate("change"));

        $form->onSuccess[] = callback($this, 'changePasswordFormSubmitted');
        
        $id = intval($this->getParameter("id"));
        
        if ($id > 0) {
            $user = $this->em->getRepository("\CMS\User\Models\User")->find($id);

            if ($user === null) {
                $this->flashMessage($this->translate("editWrongId"));
                $this->redirect(":User:User:default");
            }
            
            $form->setDefaults(array("id" => $user->id));
        }
        
        return $form;
    }
    
    // TODO: odstranit
    public function changePasswordFormSubmitted(Form $form) {
        $values = $form->getValues();
        
        $user = $this->em->getRepository("\CMS\User\Models\User")->find($values["id"]);
        $currPassword = sha1(substr($user->username, -3) . $values["currPass"]);        
        
        if ($user->password != $currPassword) {
            $form->addError($this->translate("currentPasswordWrong"));
        }
        
        if ($values["password"] != $values["passwordRep"]) {
            $form->addError($this->translate("passwordsNoMatch"));
        }
        
        if (!$form->hasErrors()) {
            $user->setPassword(sha1(substr($user->username, -3) . $values["password"]));
            $this->em->flush();
            $this->flashMessage($this->translate("passwordChangeSucceeded"));
            $this->redirect(":User:User:default");
        }
    } 
}
